package top.kaoshanji.p1ch04a;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;

/**
 * 代码清单 p1ch04a-04：对整个文件进行编码的示例
 * 并未执行...
 * author kaoshanji
 * ^_^
 * create time 2025/1/14 18:29
 */
public class CharsetEncoderExample02 {

    private static final Logger logger = LogManager.getLogger(CharsetEncoderExample02.class);

    public static void main(String[] args) throws IOException {
        logger.info("...代码清单 p1ch04a-04：对整个文件进行编码的示例...");

        CharsetEncoderExample02 example = new CharsetEncoderExample02();
        example.encodeFile();

    }

    public void encodeFile() throws IOException {
        Charset charset = Charset.forName("GB18030");
        CharsetEncoder encoder = charset.newEncoder();
        encoder.onMalformedInput(CodingErrorAction.IGNORE);
        encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);

        ByteBuffer outputBuffer = ByteBuffer.allocate(128);
        List<String> lines = Files.readAllLines(Paths.get("test.htm"), StandardCharsets.UTF_8);

        try (FileChannel descChannel = FileChannel.open(Paths.get("result.htm"),
                StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {

            for (String line: lines) {
                CharBuffer charBuffer = CharBuffer.wrap(line);
                while (true) {
                    CoderResult result = encoder.encode(charBuffer, outputBuffer, false);
                    if (result.isOverflow()) {
                        writeToChannel(descChannel, outputBuffer);
                    } else if (result.isUnderflow()) {
                        break;
                    }
                }
            }

            writeToChannel(descChannel, outputBuffer);
            encoder.encode(CharBuffer.allocate(0), outputBuffer, true);

            CoderResult result = encoder.flush(outputBuffer);
            if (result.isOverflow()) {
                ByteBuffer newBuffer = ByteBuffer.allocate(1024);
                encoder.flush(newBuffer);
                writeToChannel(descChannel, newBuffer);
            } else {
                writeToChannel(descChannel, outputBuffer);
            }
        }
    }


    private void writeToChannel(WritableByteChannel channel, ByteBuffer buffer) throws IOException {
        buffer.flip();
        channel.write(buffer);
        buffer.compact();
    }



}
